/*
 * TSPPathMatrix.cpp
 *
 *  Created on: Feb 28, 2011
 *      Author: santiago
 */

#include <iostream>
#include <assert.h>
#include <vector>
#include "TSPPath.h"
#include "TSPPathMatrix.h"
#include "GlobalDefs.h"

using namespace std;

TSPPathMatrix::TSPPathMatrix(unsigned int cant_nodos): _cant_nodos(cant_nodos) {
	_P.reserve(cant_nodos);

	vector<TSPPath*> *rowP;
	for (unsigned int nodeIndex = 0; nodeIndex < cant_nodos; nodeIndex++) {
		rowP = new vector<TSPPath*>();
		rowP->reserve(nodeIndex+1);

		for (unsigned int destiantionNodeIndex = 0;
				destiantionNodeIndex < nodeIndex + 1; destiantionNodeIndex++) {

			rowP->push_back((TSPPath*)NULL);
		}

		_P.push_back(*rowP);
		delete rowP;
	}

//	if (DEBUG) {
//		cout << "[DEBUG] <TSPPathMatrix> cant_nodos: " << cant_nodos << endl;
//		cout << "[DEBUG] <TSPPathMatrix> P size: " << _P.size() << endl;
//	}
}

TSPPathMatrix::~TSPPathMatrix() {
	for (unsigned int i = 0; i < _P.size(); i++) {
		for (unsigned int j = 0; j < _P[i].size(); j++) {
			if (_P[i][j] != NULL) delete _P[i][j];
		}
	}
}

void TSPPathMatrix::convert_to_matrix(unsigned int node_index_1, unsigned int node_index_2, unsigned int &first_node_index, unsigned int &second_node_index) const {
	if (node_index_1 < node_index_2) {
		first_node_index = node_index_2;
		second_node_index = node_index_1;
	} else {
		first_node_index = node_index_1;
		second_node_index = node_index_2;
	}

//	if (DEBUG) {
//		cout << "[DEBUG] <TSPPathMatrix> cant_nodos: " << _cant_nodos << endl;
//		cout << "[DEBUG] <TSPPathMatrix> P size: " << _P.size() << endl;
//		cout << "[DEBUG] <TSPPathMatrix> first_node_index: " << first_node_index << endl;
//		cout << "[DEBUG] <TSPPathMatrix> second_node_index: " << second_node_index << endl;
//	}

	assert(_P.size() > first_node_index);
	assert(_P[first_node_index].size() > second_node_index);
}

TSPPath* TSPPathMatrix::get_path(unsigned int node_i, unsigned int node_j) {
	unsigned int first_node_index;
	unsigned int second_node_index;
	convert_to_matrix(node_i, node_j, first_node_index, second_node_index);

	return _P[first_node_index][second_node_index];
}

void TSPPathMatrix::set_path(unsigned int node_i, unsigned int node_j, TSPPath* path) {
	unsigned int first_node_index;
	unsigned int second_node_index;
	convert_to_matrix(node_i, node_j, first_node_index, second_node_index);

	_P[first_node_index][second_node_index] = path;
}

void TSPPathMatrix::remove_path(unsigned int node_i, unsigned int node_j) {
	unsigned int first_node_index;
	unsigned int second_node_index;
	convert_to_matrix(node_i, node_j, first_node_index, second_node_index);

	if (_P[first_node_index][second_node_index] != NULL) {
		delete _P[first_node_index][second_node_index];
		_P[first_node_index][second_node_index] = NULL;
	}
}

int TSPPathMatrix::size() const {
	return _cant_nodos;
}

void TSPPathMatrix::show() const {
	for (unsigned int i = 0; i < _cant_nodos; i++) {
		for (unsigned int j = 0; j < i; j++) {
			if (_P[i][j] != NULL) {
				_P[i][j]->show();
				cout << endl;
			}
		}
	}
}
